from aiogram import Router, types, F
from aiogram.filters import CommandStart, CommandObject
from aiogram.fsm.context import FSMContext

from database import models
from database.models import TgUser
from tg_bot.filters.command_filter import WithDeepLink
from tg_bot.filters.user_filter import IsRegistered
from tg_bot.handlers.user.menu_cmd import menu_cmd_answer
from tg_bot.handlers.user.personal_account import personal_account
from tg_bot.keyboards import reply
from tg_bot.services.text import not_correct_input
from tg_bot.states.registration import Registration

reg_router = Router()
reg_router.message.filter(IsRegistered(False))


@reg_router.message(CommandStart(), WithDeepLink(False))
async def register_start_cmd(message: types.Message, state: FSMContext):
    """
    Команда /start для прохождения регистрации без диплинка.

    ----
    :param message: Сообщение тг.
    :param state: Состояние пользователя.
    :return: Запрос номера телефона по кнопке.
    """
    data = await state.get_data()
    invite_by = data.get('invite_by')
    await message.answer(text=f'Приветствую, {message.from_user.first_name}!\n'
                              f'Для регистрации в боте отправьте номер телефона, нажав '
                              f'на клавиатуру!',
                         reply_markup=reply.phone_keyboard)
    await state.set_state(Registration.phone_number)
    await state.update_data({'invite_by': invite_by})


@reg_router.message(CommandStart(True, magic=F.args.isdigit()), WithDeepLink(True))
async def register_start_cmd_with_link(message: types.Message, state: FSMContext, command: CommandObject):
    """
    Команда /start для прохождения регистрации с потенциальной реферальной ссылкой.

    ----
    :param message: Сообщение тг.
    :param state: Состояние пользователя.
    :param command: Команда с диплинком.
    :return: None.
    """
    if command.args:
        await state.update_data({'invite_by': command.args})
    await register_start_cmd(message, state)


@reg_router.message(CommandStart(True, magic=F.args.startswith('seat_')))
async def not_registered_user_to_menu(message: types.Message,
                                      state: FSMContext,
                                      command: CommandObject):
    """
    Команда /start для прохождения регистрации и перехода в меню с привязкой к столу.

    ----
    :param message: Сообщение тг.
    :param state: Состояние пользователя.
    :param command: Команда с диплинком.
    :return: None.
    """
    if command.args:
        seat_id: int = int(command.args.replace('seat_', ''))
        seat: models.Seat = models.Seat.objects.filter(pk=seat_id).first()
        await state.update_data({'seat': seat})
        await register_start_cmd(message, state)


@reg_router.message(F.content_type == 'contact', Registration.phone_number)
async def get_number(message: types.Message, state: FSMContext):
    """
    Ловим сообщения с контактом. Проверяем, принадлежит ли контакт юзеру или нет.

    :param message: Message
    :param state: State
    :return: None
    """
    if message.contact.phone_number and message.contact.user_id == message.from_user.id:
        number = message.contact.phone_number.replace('+', '')
        await message.answer('Введите ваше имя: ', reply_markup=types.ReplyKeyboardRemove())
        await state.set_state(Registration.name)
        await state.update_data({'phone_number': f'+{number}'})
    else:
        await not_correct_input(message, 'Вы отправили не свой номер телефона!')


@reg_router.message(Registration.name)
async def get_name(message: types.Message, state: FSMContext):
    """
    Регистрация пользователя по собранным данным и перенаправление его в личный кабинет или меню.

    ----
    :param message: Сообщение тг с именем.
    :param state: Состояние пользователя.
    :return: None
    """
    data = await state.get_data()
    seat: models.Seat = data.get('seat')
    invite_by = data.get('invite_by')
    phone_number = data.get('phone_number')
    if user := TgUser.register(
        user_id=message.from_user.id,
        username=message.from_user.username,
        name=message.text,
        phone_number=phone_number,
        deep_link=invite_by
    ):
        TgUser.create_main_admin(user)
    else:
        return message.answer('Что-то пошло не так...')
    await state.clear()
    if seat:
        return menu_cmd_answer(message, state)
    return await personal_account(message, state, user)


@reg_router.message()
async def any_content_from_not_reg_user(message: types.Message, state: FSMContext):
    """
    Отвечаем на все сообщения незарегистрированным пользователям с просьбой пройти регистрацию!

    ----
    :param message: Сообщение тг.
    :param state: Состояние пользователя.
    :return: None
    """
    text = f'{message.from_user.first_name}, вы не прошли регистрацию!\n\n' \
           f'Для регистрации в боте отправьте номер телефона, нажав ' \
           f'на клавиатуру!'
    await message.answer(text, reply_markup=reply.phone_keyboard)
    await state.set_state(Registration.phone_number)
